//
//  NSString+LYAdd.m
//  LYDevelopKit
//
//  Created by 李阳 on 2018/5/26.
//

#import "NSString+LYAdd.h"
#import "LYNSMacro.h"

LYSYNTH_DUMMY_CLASS(NSString_LYAdd)

@implementation NSString (LYAdd)

#pragma mark - Utilities

/// 获取字符串(或汉字)首字母
- (NSString *)firstCharacter
{
    NSMutableString *str = [NSMutableString stringWithString:self];
    CFStringTransform((CFMutableStringRef)str, NULL, kCFStringTransformMandarinLatin, NO);
    CFStringTransform((CFMutableStringRef)str, NULL, kCFStringTransformStripDiacritics, NO);
    NSString *pinyin = [str capitalizedString];
    return [pinyin substringToIndex:1];
}

/// 按顺序字符串中数字出现的书序保留数字
- (NSString *)retenteOfNumbers
{
    NSCharacterSet *set = [[NSCharacterSet characterSetWithCharactersInString:@".0123456789"] invertedSet];
    return [[self componentsSeparatedByCharactersInSet:set] componentsJoinedByString:@""];
}

- (NSString *)retenteWhenOccurrencesInSet:(NSString *)setString
{
    NSCharacterSet *set = [[NSCharacterSet characterSetWithCharactersInString:setString] invertedSet];
    return [[self componentsSeparatedByCharactersInSet:set] componentsJoinedByString:@""];
}

- (NSString *)subStringToString:(NSString *)str
{
    NSUInteger location = [self rangeOfString:str].location;
    if (location == NSNotFound)
    {
        return self;
    }
    return [self substringToIndex:location];
}
/// 生成从指定字符开始的字符串
- (NSString *)subStringFromString:(NSString *)str
{
    NSUInteger location = [self rangeOfString:str].location;
    if (location == NSNotFound)
    {
        return self;
    }
    return [self substringFromIndex:location];
}
- (NSString *)removeString:(NSString *)str
{
    NSRange range = [self rangeOfString:str];
    if (range.location == NSNotFound)
    {
        return self;
    }
    return [self stringByReplacingCharactersInRange:range withString:@""];
}

- (NSString *)substringFromString:(NSString *)fromString toString:(NSString *)toString
{
    NSRange to = [self rangeOfString:toString];
    if (to.location == NSNotFound) return nil;
    NSRange from = [self rangeOfString:fromString];
    if (from.location == NSNotFound) return nil;
    NSInteger start = from.location + from.length;
    return [self substringWithRange:(NSRange){start, to.location - start}];
}

- (void)enumerateSequenceCharacterUsingBlock:(void (^)(NSString *, NSRange, BOOL *))block
{
    NSParameterAssert(block);
    NSRange range = NSMakeRange(0, 0);
    BOOL flag = NO;
    for (NSInteger i = 0; i < self.length; i += range.length)
    {
        range = [self rangeOfComposedCharacterSequenceAtIndex:i];
        NSString *s = [self substringWithRange:range];
        block(s, range, &flag);
        if (flag)
        {
            break;
        }
    }
}


#pragma mark - Encode and decode

/// 表情编码
- (NSString *)stringByEmojiEncode
{
    NSString *uniStr = [NSString stringWithUTF8String:[self UTF8String]];
    NSData *uniData = [uniStr dataUsingEncoding:NSNonLossyASCIIStringEncoding];
    return [[NSString alloc] initWithData:uniData encoding:NSUTF8StringEncoding];
}
/// 表情解码
- (NSString *)stringByEmojiDecode
{
    const char *jsonString = [self UTF8String];
    NSData *jsonData = [NSData dataWithBytes:jsonString length:strlen(jsonString)];
    return [[NSString alloc] initWithData:jsonData encoding:NSNonLossyASCIIStringEncoding];
}


#pragma mark - Regular


- (BOOL)matchesRegular:(NSString *)regular
{
    if (regular.length < 1) return NO;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regular];
    return [predicate evaluateWithObject:self];
}

/// 邮箱验证
- (BOOL)isEmail
{
    // @"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
    return [self matchesRegular:@"^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"];
}
/// 手机号验证
- (BOOL)isPhoneNo
{
    return [self matchesRegular:@"^1[3|4|5|7|8][0-9]\\d{8}$"];
}

//- (BOOL)containsEmoji
//{
//    if (!self.length)
//    {
//        return NO;
//    }
//    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]" options:NSRegularExpressionCaseInsensitive error:nil];
//    return [regex firstMatchInString:self options:0 range:(NSRange){0, self.length}].range.length;
//}

- (BOOL)containsEmoji
{
    if (!self.length)
    {
        return NO;
    }
    __block BOOL returnValue = NO;
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
     ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
         
         const unichar hs = [substring characterAtIndex:0];
         // surrogate pair
         if (0xd800 <= hs && hs <= 0xdbff) {
             if (substring.length > 1) {
                 const unichar ls = [substring characterAtIndex:1];
                 const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                 if (0x1d000 <= uc && uc <= 0x1f77f) {
                     returnValue = YES;
                 }
             }
         } else if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             if (ls == 0x20e3) {
                 returnValue = YES;
             }
             
         } else {
             // non surrogate
             if (0x2100 <= hs && hs <= 0x27ff) {
                 returnValue = YES;
             } else if (0x2B05 <= hs && hs <= 0x2b07) {
                 returnValue = YES;
             } else if (0x2934 <= hs && hs <= 0x2935) {
                 returnValue = YES;
             } else if (0x3297 <= hs && hs <= 0x3299) {
                 returnValue = YES;
             } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                 returnValue = YES;
             }
         }
     }];
    
    return returnValue;
}

//- (BOOL)containsSudokuNumber
//{
//    if (!self.length)
//    {
//        return NO;
//    }
//    NSString *other = @"➋➌➍➎➏➐➑➒";     //九宫格的输入值
//    return [other rangeOfString:self].location != NSNotFound;
//}

- (BOOL)containsSudokuNumber
{
    if (!self.length)
    {
        return NO;
    }
    __block BOOL returnValue = NO;
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
     ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
         
         const unichar hs = [substring characterAtIndex:0];
         
         if (0x2100 <= hs && hs <= 0x27ff)
         {
             // U+278b ➋ ~ U+2792➒"
             if (0x278b <= hs && hs <= 0x2792)
             {
                 returnValue = YES;
             }
             // U+263b u'☻'
             else if (0x263b == hs)
             {
                 returnValue = YES;
             }
         }
     }];
    return returnValue;
}

@end


inline NSString *Round(CGFloat decimal, int precision)
{
    if (precision < 1 || precision > 5)
    {
      return [NSString stringWithFormat:@"%.0f", round(decimal)];
    }
    unsigned power = pow(10, precision);
    CGFloat result = round(decimal * power) / power;
    switch (precision)
    {
        case 1: return [NSString stringWithFormat:@"%.1f", result];
        case 2: return [NSString stringWithFormat:@"%.2f", result];
        case 3: return [NSString stringWithFormat:@"%.3f", result];
        case 4: return [NSString stringWithFormat:@"%.4f", result];
        case 5: return [NSString stringWithFormat:@"%.5f", result];
    }
    return nil;
}


